#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <NvInfer.h>
#include <vector>
#include <NvOnnxParser.h>
#include </usr/local/cuda/include/cuda_runtime.h>
#include </usr/local/cuda/include/cuda_runtime_api.h>
using namespace cv;
using namespace std;
using namespace nvinfer1;
using namespace cuda;

typedef struct Configuration{
    // 对象的置信度
    float conf_threshold;
    // 非极大抑制置信度
    float nms_threshold;
    // 对像类别的执行度
    float obj_threshold;
    // 模型文件的路劲
    string model_path;
    // class names
    std::vector<std::string> class_names;
    // top k
    int topK;
}Configuration;

// 定义Boxinfo的结构类型
typedef struct BoxInfo{
    // 左上角的位置
    int x1;
    int y1;
    // 右下角的位置
    int x2;
    int y2;
    // 对象了类别的置信度
    float score;
    // 对象的不同类别
    int label;

    int width;
    int height;
    std::string lable_name;
    void updatewidth(){
        width = y1 - x1;
        height = y2 - x2;
    }
    void updateLable(std::vector<std::string> lables){
        if(lables.empty()){
            return;
        }
        lable_name = lables.at(label);
    }

}BoxInfo;

class YOLOv10{
    public:
        YOLOv10();
        ~YOLOv10();
        std::vector<BoxInfo> detect(Mat& frame);
        void normalize_(cv::Mat &img);
        void nms(vector<BoxInfo> &input_boxes);
        cv::Mat resize_image(cv::Mat srcimg);
        void loadOnnx(const string strName);
        void loadTrt(const string strName);
        void UnInit();
        cv::Mat YOLOv10_Draw_Line(std::vector<BoxInfo>  &generate_boxes,cv::Mat imag);
        void init(Configuration config);

        vector<float> input_image_;		// 输入图片

        
    private:
        float conf_threshold;
        float nms_threshold;
        float obj_threshold;
        int in_p_width;
        int in_p_height;
        std::vector<std::string> classes;

   
        

        const bool keep_ratio = true;
        
        // std::unique_ptr<ICudaEngine> m_CudaEngine;
        // std::unique_ptr<IRuntime> m_CudaRuntime;
        // std::unique_ptr<IExecutionContext> m_CudaExecutionContext;
        
        ICudaEngine *m_CudaEngine;
        IRuntime *m_CudaRuntime;
        IExecutionContext *m_CudaExecutionContext;
        cudaStream_t m_CudaStream;


        int m_iInputIndex;
        int m_iOutputIndex;
        int m_iClassNums;
        int m_iBoxNums;
        cv::Size m_InputSize;
        void * m_ArrayDevMemory[2]{0};
        void * m_ArrayHostMemory[2]{0};

        int m_ArraySize[2]{0};

        vector<cv::Mat> m_InputWrapper{};


        int input_image_height  {};
        int input_image_widht{};
        
        int newh = {};
        int neww = {};


        
};